by Michael Morrison
In This Chapter
Printing is a significant part of most document-centric applications because most users require a hard copy of their work at some point. Although the paperless office has received a lot of hype, in reality it isnt as easy giving up paper as many people would like to believe. So, for the foreseeable future at least, printing is still something programmers have to support in most applications. Fortunately, MFC provides solid support for printing within the document/view architecture that removes a lot of the burden of printing from the programmer.
This chapter tackles printing in MFC and how it affects the design and construction of MFC applications. Youll learn about the MFC classes used to support printing and how to use them to build WYSIWYG (what you see is what you get) applications.
In Chapter 4, Painting, Device Contexts, Bitmaps, and Fonts, you learned how MFC employs a device context to provide an abstraction for a drawing surface. This abstraction enables you to draw graphics to virtually any graphical output device with a suitable Windows graphics driver. Printing using MFC is handled in a similar manner. Printing to a printer is little different from drawing to the screenin both cases a device context is used to abstract the drawing process. From the perspective of Windows, a printer is considered just another graphical output device, and therefore requires a graphics driver in order to be used in Windows.
It isnt just coincidental that printers are handled no differently than monitors. It is a very beneficial part of the design of Windows to enable developers to draw graphics to a printer using the same code that they use to draw graphics to the screen. As an example, consider a graphical application such as the Paint application that ships with Windows 98. This application could use practically the same code to render a drawing to the printer as it does to render a drawing to the screen. On the other hand, adding printing support to form-based applications isnt so simple, because they rely on child controls as the basis for their user interface. In this case, it is up to the programmer to implement a custom printing solution. Even so, you can still use familiar Windows GDI operations and an MFC device context object to carry out the printing.
Speaking of supporting printing in an application, youre probably aware of the fact that print preview has become a standard feature in many applications. Print preview is a visualization of a document on the screen as it will appear on the printed page. You can think of print preview as a simulated print to a special preview window. In fact, it is common to use the same code in print preview as in the actual printing. MFC provides specific support for print preview in addition to its printing support.
Before the days of MFC, you had to use Win32 functions to carry out the arduous task of printing. Trust meadding printing support to an application using straight Win32 functions was a hassle at best, and in many cases could turn into a nightmare. The problem wasnt that drawing graphics to the printer is difficult but that it required myriad Win32 function calls to move the process along. There were also complex data structures that you had to initialize and use properly. And last but not least, you were responsible for implementing a special modeless dialog box that allowed the user to cancel out of printing a lengthy document.
MFC has simplified the process of printing significantly, thanks primarily to its document/view architecture. As a matter of fact, MFCs document/view architecture provides you with default support for printing without your having to do any additional work. By default, MFC will use the OnDraw() member function in your view class to print a document. If you recall, OnDraw() accepts a pointer to a CDC object as its only parameter. During the printing process, this CDC object represents a printer device context instead of a screen device context.
Of course, in most cases you will want to expand on MFCs default printing support and add print features such as headers and footers, along with pagination of documents. MFC provides a printing framework of virtual member functions that makes it easy to add exactly the functionality you need. You can add full-featured printing support to an application, including print preview, by simply overriding appropriate member functions in a view class.
The majority of MFCs printing support is encapsulated in the CView class, which means that all document/view applications have some form of default printing. There is also a set of special printing member functions in CView that you can use to alter the way in which documents are printed. For example, you must alter the default CView printing functionality if you want to print multiple pages or if you want to print a header or footer on a page.
Table 9.1 lists the most important CView member functions used for printing.
| Member Function | Description |
|---|---|
| OnPreparePrinting() | Called before a document is printed or previewed |
| DoPreparePrinting() | Displays the Print dialog box and creates a printer device context (DC); called from OnPreparePrinting() |
| OnBeginPrinting() | Called when a print job begins; allocates print-related GDI resources |
| OnPrepareDC() | Called before OnDraw() to prepare a DC for drawing |
| OnPrint() | Called to print or preview a document page |
| OnEndPrintPreview() | Called when the user exits preview mode |
| OnEndPrinting() | Called when a print job ends; frees print-related GDI resources |